# -*- coding: utf-8 -*-
import time
import numpy as np
from enum import Enum
from sqlalchemy import true
from gobang_engine import *
from PyQt5 import QtCore, QtGui, QtWidgets
import sys
from PyQt5.QtCore import Qt, QThread, pyqtSignal, QPoint
from PyQt5.QtGui import QIcon, QPixmap
from PyQt5.QtWidgets import QMainWindow, QApplication, QLabel, QAction
from gobang_ui import Ui_MainWindow
from copy import deepcopy


class GameTime(QThread):
    _signal = pyqtSignal(str)

    def __init__(self, label):
        self.label = label
        super(GameTime, self).__init__()

    def set_status(self, status):
        self.status = status

    def run(self):
        start = time.time()
        while self.status:
            time.sleep(1)
            end = time.time()
            second = int(end-start)
            display_time = str(int(second/60))+":"+str(second % 60)
            # print(display_time)
            self._signal.emit(display_time)


class PieceCursor(object):
    def __init__(self, parent):
        self.cursor = [QLabel(parent) for i in range(8)]
        for ob in self.cursor:
            ob.setMouseTracking(True)
            ob.setGeometry(0, 0, 0, 0)
            ob.setStyleSheet("background-color:red")

    def moveTo(self, pos):
        MARGIN = 20
        LINEWIDTH = 3
        HEIGHT = 15
        self.cursor[0].setGeometry(
            pos.x()-MARGIN, pos.y()-MARGIN, LINEWIDTH, HEIGHT)  # 竖线
        self.cursor[1].setGeometry(
            pos.x()-MARGIN, pos.y()-MARGIN, HEIGHT, LINEWIDTH)  # 横线
        self.cursor[2].setGeometry(
            pos.x() + MARGIN, pos.y() - MARGIN, LINEWIDTH, HEIGHT)  # 竖线
        self.cursor[3].setGeometry(
            pos.x()+MARGIN - HEIGHT, pos.y() - MARGIN, HEIGHT, LINEWIDTH)  # 横线
        self.cursor[4].setGeometry(
            pos.x()-MARGIN, pos.y()+MARGIN-HEIGHT, LINEWIDTH, HEIGHT)  # 竖线
        self.cursor[5].setGeometry(
            pos.x()-MARGIN, pos.y()+MARGIN, HEIGHT, LINEWIDTH)  # 横线
        self.cursor[6].setGeometry(
            pos.x()+MARGIN, pos.y()+MARGIN-HEIGHT, LINEWIDTH, HEIGHT)  # 竖线
        self.cursor[7].setGeometry(
            pos.x()+MARGIN - HEIGHT, pos.y()+MARGIN, HEIGHT, LINEWIDTH)  # 横线

        for ob in self.cursor:
            ob.show()

    def hide(self):
        for ob in self.cursor:
            ob.hide()


class MyMainForm(QMainWindow, Ui_MainWindow):
    chessboard = []
    originPosition = (40, 70)
    step = 0
    status = 0

    def __init__(self, parent=None):
        super(MyMainForm, self).__init__(parent)
        self.gobangEngine = GobangEngine(GOBANG_ROW,GOBANG_COL,GOBANG_GROUP)
        self.setupUi(self)
        self.centralWidget().setCursor(Qt.PointingHandCursor)  # 鼠标变成手指形状
        self.setMouseTracking(True)
        self.centralWidget().setMouseTracking(True)
        self.chessboard.setMouseTracking(True)
        self.result_label.setMouseTracking(True)

        self.black = QPixmap('./designer/image/black.png')
        self.white = QPixmap('./designer/image/white.png')

        reAction = QAction('重来一局', self)
        self.toolbar = self.addToolBar('standard')
        self.toolbar.addAction(reAction)
        reAction.triggered.connect(self.startGame)

        self.cursor = PieceCursor(self)

        # 棋盘状态
        self.chessboard = np.zeros((15, 15), dtype=int)

        self.pieces = [QLabel(self)
                       for i in range(225)]  # 新建225个棋子标签，准备在棋盘上绘制棋子
        for piece in self.pieces:
            piece.setMouseTracking(True)
            piece.setVisible(True)  # 图片可视
            piece.setGeometry(0, 0, 0, 0)
            piece.setScaledContents(True)  # 图片大小根据标签大小可变

        # # 实例化计时线程
        self.game_time = GameTime(self.label_3)
        self.game_time._signal.connect(self.set_time)
        self.game_time.set_status(1)
        self.game_time.start()

        # # 棋局状态，1为开始对局，0为停止
        self.status = 1
        # # 设置已下步数
        self.step = 0

    def startGame(self):
        print("hello world!")
        nullPixmap = QPixmap(0, 0)
        self.result_label.setPixmap(nullPixmap)

        for i in range(self.step):
            self.pieces[i].setPixmap(nullPixmap)

        for x in range(15):
            for y in range(15):
                self.chessboard[x][y] = 0

        # # 棋局状态，1为开始对局，0为停止
        self.status = 1
        # # 设置已下步数
        self.step = 0

        self.gobangEngine.reset()
        self.game_time.set_status(1)
        self.game_time.start()

        return

    def set_time(self, time):
        self.label_3.setText("时间：{}".format(time))

    def getPeicePosByMousePos(self, e):
        x = -1
        for i in range(15):
            posX = self.originPosition[0] + 65.7*i
            if (e.x() >= posX - 20 and e.x() <= posX + 20):
                x = i
                break

        y = -1
        for i in range(15):
            posY = self.originPosition[1] + 65.35*i
            if (e.y() >= posY - 20 and e.y() <= posY + 20):
                y = i
                break

        return (x, y)

    def mouseMoveEvent(self, e):  # 黑色棋子随鼠标移动
        # 计算鼠标悬浮位置对应的棋子位置并显示
        # 棋盘每格的空间为65*65
        # 棋盘的第一个点是(40,70)
        # 围绕每个中心点上下左右(20,20)的方框，如果鼠标坐标在该方框内，则画一个特殊符号，鼠标点击后可以落子
        (x, y) = self.getPeicePosByMousePos(e)

        #print("x:%d,y:%d" % (x, y))
        # print(e.pos())

        if (x != -1 and y != -1 and self.chessboard[x][y] == 0 and self.status != 0):
            # 移动特殊符号
            centerPoint = QPoint(int(
                self.originPosition[0]+x*65.7), int(self.originPosition[1]+y*65.35))
            self.cursor.moveTo(centerPoint)
        else:
            # 隐藏特殊符号
            self.cursor.hide()

        #self.mouse_point.move(e.x() - 16, e.y() - 16)
        super().mouseMoveEvent(e)
    # 玩家下棋

    def mousePressEvent(self, e):
        if e.button() != Qt.LeftButton or self.status == 0:
            super().mousePressEvent(e)
            return

        (x, y) = self.getPeicePosByMousePos(e)
        valide = self.placePiece(x, y, WHITE_PIECES)
        if (not valide):
            super().mousePressEvent(e)
            return

        # ai下棋
        done = self.gobangEngine.man_act([y, x, WHITE_PIECES])
        # 判断输赢,根据结果决定是否继续棋局
        if (done):
            print("白子胜出")
            self.gobangEngine.env.render()
            # 计时停止
            self.game_time.set_status(0)
            # 设置棋局状态为0
            self.status = 0
            win = QPixmap('./designer/image/win-removebg-preview.png')

            self.result_label.setPixmap(win)
            self.result_label.setGeometry(140, 232, 700, 150)
            super().mousePressEvent(e)
            return

        self.status = 0
        self.label_7.setText("让我想一下......")
        # ai下棋
        action, done = self.gobangEngine.ai_act(BLACK_PIECES)
        result = [action[0], action[0], 2]
        self.placePiece(action[1], action[0], BLACK_PIECES)
        self.status = 1
        self.label_7.setText("轮到你了！")

        if (done):
            print("黑子胜出")
            self.gobangEngine.env.render()
            # 计时停止
            self.game_time.set_status(0)
            # 设置棋局状态为0
            self.status = 0
            win = QPixmap(
                './designer/image/lost-removebg-preview.png')
            self.result_label.setPixmap(win)
            self.result_label.setGeometry(140, 232, 700, 150)

        super().mousePressEvent(e)
        return

    def placePiece(self, i, j, color):
        if (i == -1 or j == -1 or self.chessboard[i][j] != 0):
            return False

        self.chessboard[i][j] = color
        if color == WHITE_PIECES:
            self.pieces[self.step].setPixmap(self.white)  # 放置白色棋子
        elif color == BLACK_PIECES:
            self.pieces[self.step].setPixmap(self.black)  # 放置黑色棋子
        self.pieces[self.step].setGeometry(
            int(self.originPosition[0] + i*65.7-32), int(self.originPosition[0] + j*65.35), 64, 64)  # 设置位置，大小
        self.step += 1
        self.label_2.setText("步数：{}".format(self.step))
        return True


def main():
    # 固定的，PyQt5程序都需要QApplication对象。sys.argv是命令行参数列表，确保程序可以双击运行
    app = QApplication(sys.argv)
    # 初始化
    myWin = MyMainForm()
    # 设置标题图标
    myWin.setWindowIcon(QIcon('./favicon.ico'))
    # 设置标题
    myWin.setWindowTitle('欢乐五子棋')
    # 将窗口控件显示在屏幕上
    myWin.show()
    # 程序运行，sys.exit方法确保程序完整退出。
    sys.exit(app.exec_())


if __name__ == '__main__':
    main()
